home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
presto
/
prest_04.lha
/
src
/
spinlock_impl.h
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-06
|
2KB
|
86 lines
// Spinlock inline implementations
// Must follow defs for threads, but precede everything else.
//
#if defined(DO_SPINLOCK_INLINE) || defined(_SPINLOCK_C)
/*
* Optimized version of S_LOCK to only make the procedure call
* if the lock is held. Would really like to use S_LOCK here,
* but (potentially) inline functions can't handle loops.
*/
SPINLOCK_INLINE
void
Spinlock::lock()
{
#ifdef ns32000
char *lock_alm = &_alm_base[ALM_HASH(sl_lock)];
#endif
//
// Must mark ourselves in the lock even before we acquire it.
// Otherwise, we could hold the lock and be preempted. If we
// were holding the lock on something that the preemption code
// needed (or someone else, in order to ensure we run), we would
// deadlock. Must make lock acquisition and thread in spin cs
// marking atomic.
//
#ifndef NO_PREEMPT
thisthread->holdingspinlock();
#endif NO_PREEMPT
#ifdef ns32000
if (sl_lock == L_LOCKED) // u lose
(void)s_lock(&sl_lock);
else if (*lock_alm & ALM_LOCKED) // u lose
(void)s_lock(&sl_lock);
else if (sl_lock == L_LOCKED) { // u lose (race condition)
*lock_alm = ALM_UNLOCKED;
(void)s_lock(&sl_lock);
} else { // u win
sl_lock = L_LOCKED;
*lock_alm = ALM_UNLOCKED;
}
#else
//
// No ALM's in Symmetry. We use S_LOCK() and to avoid
// another out-of-line call. Since C++ doesn't understand
// asm-functions, must use "CC +hasmdefs.h".
//
// On the vax, S_LOCK is a function call to s_lock() in vax_lock.s.
// Should probably be inline.
//
(void) S_LOCK(&sl_lock);
#endif
}
SPINLOCK_INLINE
void
Spinlock::unlock()
{
(void) S_UNLOCK(&sl_lock);
#ifndef NO_PREEMPT
thisthread->releasingspinlock();
#endif NO_PREEMPT
}
SPINLOCK_INLINE
Spinlock::~Spinlock()
{
//
// We should abort if the lock is not free. (?) XXX
// For now just unlock it for backward compatibility.
//
if (testlock())
unlock();
}
#endif DO_SPINLOCK_INLINE || SPINLOCK_C